package com.xf.auth.controller;


import com.xf.auth.service.ValidateCodeService;
import com.xf.common.core.constant.CommonConstants;
import com.xf.common.core.domain.DmpResult;
import com.xf.common.core.entity.constant.StringConstant;
import com.xf.common.core.exception.ValidateCodeException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xufeng
 */
@Slf4j
@Controller
@RequiredArgsConstructor
@SessionAttributes("authorizationRequest")
public class SecurityController {

    private final ValidateCodeService validateCodeService;
    private final ConsumerTokenServices consumerTokenServices;
    private final RequestCache requestCache = new HttpSessionRequestCache();
    private final ClientDetailsService clientDetailsService;

    @ResponseBody
    @GetMapping("user")
    public Principal currentUser(Principal principal) {
        return principal;
    }

    @ResponseBody
    @GetMapping("captcha")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException, ValidateCodeException {
        validateCodeService.create(request, response);
    }

    /**
     * 跳转授权页
     *
     * @return
     */
    @SneakyThrows(Exception.class)
    @RequestMapping("login")
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response) {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest == null) {
            ModelAndView view = new ModelAndView();
            view.setViewName("login");
            view.addObject("errorText", "请通过授权码模式跳转到该页面");
            return view;
        }
        ModelAndView view = new ModelAndView();
        //自定义页面名字，resources\templates\login.html
        view.setViewName("login");
        String[] paramTenantId = savedRequest.getParameterValues(CommonConstants.ORGANIZATION_ID);
        String tenantId = paramTenantId[0];
        view.addObject("tenantId", tenantId);
        return view;
    }

    /**
     * 授权自定义页面
     *
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/oauth/confirm_access")
    public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpSession session, ModelAndView view) throws Exception {
        AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");
        //自定义页面名字，resources\templates\base-grant.html
        view.setViewName("base-grant");
        if (authorizationRequest != null) {
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
            Map<String, Object> app = new HashMap<>();
            //获取扩展信息 没有先写死 前端存这个字段到表里去 clientDetails.getAdditionalInformation();
            app.put("website", "http://www.baidu.com");
            app.put("appName", "xx小程序");
            view.addObject("app", app);
            //view.addObject("user", FebsUtil.getCurrentUser());
            view.addObject("clientId", authorizationRequest.getClientId());
            view.addObject("scopes", authorizationRequest.getScope());
        }
        return view;
    }

    @ResponseBody
    @DeleteMapping("signout")
    public DmpResult signout(HttpServletRequest request, @RequestHeader("Authorization") String token) {
        token = StringUtils.replace(token, "bearer ", StringConstant.EMPTY);
        consumerTokenServices.revokeToken(token);
        return DmpResult.data("signout");
    }
}
